Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 29.12.2016, 16:47
Профессор
Отправить личное сообщение для smart-create Посмотреть профиль Найти все сообщения от smart-create
 
Регистрация: 25.10.2016
Сообщений: 157

Вывод из таблицы в БД c помощью AJAX
Добрый день! Создаю что-то на подобие чата - вывод комментариев пользователей к товару на страницах интернет-магазина. Реализую вывод записей на клиенте с помощью AJAX, но не могу разобраться как выводить на страницу не все записи из таблицы подряд, а по определенному параметру. То есть у меня есть таблица с вот такой структурой:

в ней есть столбец "key_c" в котором и содержится параметр, который и должен являться переселяющим для вывода записей на ту или иную страницу. Этот параметр, берется из последнего параметра ссылки. Например товар к которому был оставлен комментарий находиться по ссылке: ../product/imy_tovara_2, значит в таблице, в строке с этим отзывом, значение "key_c" будет imy_tovara_2.
Соответственно, при выборе данных из таблицы, мне нужно каким-то образом учитывался это параметр, и в итоге было вот так:
1) ../product/imy_tovara_2 - выводятся только те комментарии в которых есть параметр "key_c" со значением imy_tovara_2;
2) ../product/imy_tovara_3 - выводятся только те комментарии в которых есть параметр "key_c" со значением imy_tovara_3;
3) и т.д.

Сейчас же у меня к сожалению на все страницы с товарами выводятся все записи из таблицы с отзывами.

Реализовано у меня все следующим образом:

1) Вот разметка блока в который выводятся комментарии:
<div class="feedback-content row pagination-page"> // родитель в который заноситься информация полученная из таблицы
	<div class="page-anchor"></div> // все записи добавляются после этого блока
	<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 text-right feedback-nav"> // родитель пагинатора
		<nav> // сам пагинатор
			<ul class="pagination"></ul>
		</nav>
	</div>
</div>


2) Вот разметка формы с помощью которой создаются комментарии:
<form id="feedback_form" method="post" action="/main_c/add_comments" >
        <input type="name" name="comments_name" class="validate-usser" placeholder="Ваше имя *">
        <input type="email" name="comments_email" class="validate-usser" placeholder="Ваше Email *">

        <input type="hidden" name="comments_key"> // в value этого импута, скрипт заносит параметр "key_c"

        <textarea name="comments_feedback" class="validate-usser" placeholder="Текст отзыва *"></textarea>
        <button type="submit" class="btn btn-7 btn-7h icon-envelope">Оставить отзыв</button>																			</form>


3) Вот контроллер и модель на сервере которые принимают данные из формы и заносят их в таблицу:
// КОНТРОЛЛЕР
function add_comments() {
		
	$comments['name']  = $_POST['comments_name'];
	$comments['email'] = $_POST['comments_email'];
	$comments['feedback'] = $_POST['comments_feedback'];
	$comments['key_c'] = $_POST['comments_key'];

	$comment_id = $this->main_model->new_comments($comments);
			
	$comment = array();
	if ($comment_id){
		$comment = $this->main_model->get_comments_limit(0,1);
	}
			
	echo json_encode($comment);
}

// МОДЕЛЬ
function new_comments($comments){

	$array = array(
		'date' => date("Y-m-d H:i:s", time()),
		'name' => $comments['name'],
		'email' => $comments['email'],
		'feedback' => $comments['feedback'],
		'key_c' => $comments['key_c']
	);
	$this->db->insert('comments', $array);
	return $this->db->insert_id();
}


4) Вот скрипты которые участвуют в работе:
// здесь определяется "хвост"(последний параметр) ссылки и заноситься в импут формы которую я указал выше
$(function(){ 
	var key_c = $('[name=comments_key]'),
		url = document.location.pathname;
	key_c.val(url.split('/')[2]);
});

var comment_limit = 3; // это переменная для пагинации, которая задаёт количество записей на одной странице, в данном случаи 3 записи на одной странице

$(function(){
	load_comments();
	
	$(".feedback-content").delegate("nav li a", "click", function(){ // здесь происходит переключение страниц пагинатора
		var page = parseInt($(this).closest('li').attr('p')) || 0;
		load_comments(page);
		return false;
	})
});

function load_comments(page){ // это ajax который и выводит все подряд записи из таблицы
	$.ajax({
		url: '/main_c/loadComments',
		type: 'POST',
		data: {
			page: page || 0,
			limit: comment_limit,
		},
		dataType: 'json',
	})
	.done(function(result){
		if (result.is_ok){
			create_nav(result.nav);
			create_comments(result.comments, true);
		}
	});
}
	
function create_comments(comments, is_remove){ // здесь задаются параметры вывода записей на страницу
	if (is_remove){
		$(".feedback-content .row.feedback__client").remove();
	}
	for (var n in comments){
		var comment = create_comment(comments[n]);
		if (is_remove){
			comment.appendTo($(".feedback-content"));
			$(".feedback-content").append($(".feedback-nav"));
		}else{
			comment.insertAfter($(".page-anchor"));
		}
	}
}
	
function create_comment(comment){ // здесь создается разметка блока с записью, параметры полученные из таблицы вставлены как ' + comment.name + ', ' + comment.date + ' и т.д.
		
	var comment = $(
		'<div class="row feedback__client">'
		+	'<div class="col-lg-10 col-md-10 col-sm-8 col-xs-12 viwe__feedback">'
		+		'<div class="row">'
		+			'<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 title__feedback">'
		+				'<span>' + comment.name + '</span><span> / </span><span>' + comment.email + '</span><span class="data__time">' + comment.date + '</span>'
		+			'</div>'
		+		'</div>'
		+		'<div class="row">'
		+			'<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 txt__feedback">'
		+				'<span>' + comment.feedback + '</span>'
		+			'</div>'
		+		'</div>'
		+	'</div>'
		+'</div>'
	);
	return comment;
}
	
function create_nav(nav){ // здесь задаётся разметка и функциональность пагинатора
		
	var ul = $(".feedback-content nav ul");
	if (!ul.find('li').length){
		var max = Math.ceil(nav.max / comment_limit);
		for (var p=0; p<max; p++){
			var li = $("<li>").attr('p', p).appendTo(ul);
			$("<a>").attr('href', '#').html(p + 1).appendTo(li);
		}
	}

	ul.find('li.active').removeClass('active');
	ul.find('li[p="'+nav.page+'"]').addClass('active');
}

$("form#feedback_form").submit(function(e){ // это обработчик формы которая создает комментарий
	e.preventDefault();
	var f = this,
		data = $(f.elements),
        s = $(f.elements).last(),
        e = s.end().slice(0, -2).removeClass('input-error').filter(function() {
            return !$.trim(this.value)
        });
    if(e.length) s.addClass('btn-error'), e.addClass('input-error'), setTimeout(function () {s.removeClass('btn-error')}, 1500);
	else {
		s.prop('disabled', 1);
        s.end().not(s);
		$.ajax({
			url: f.action,
			type: 'POST',
			data: data,
			dataType: 'json',
			success: function(data) {
				setTimeout(function () {
					create_comments(data); // здесь происходит моментальный вывод комментария на страницу в случаи успешного выполнения скрипта
				}, 1500);
				f.reset();
				s.prop('disabled', 0);
				s.removeClass('btn-error');
				s.addClass('btn-success');
				e.removeClass('input-error');
				setTimeout(function () {
					s.removeClass('btn-success');
					$('body').animate({
						scrollTop:$('.page-anchor:first').offset().top
					},500);
				}, 1000);
			},
			error: function (){
				s.addClass('btn-error');
				s.prop('disabled', 0);
				setTimeout(function () {
					s.removeClass('btn-error');
				}, 2000);
			}
		});
	}
});


5) Вот контроллер и модель к которым обращается AJAX при выводе записей из таблицы:
// КОНТРОЛЛЕР
function loadComments() {
		
	$page = isset($_POST['page']) ? (int)$_POST['page'] : 0;
	$limit = isset($_POST['limit']) ? (int)$_POST['limit'] : 3;
		
	$answer = new stdClass();
	$err = array();
		
	$answer->nav = new stdClass();
	$answer->nav->page = $page;
	$answer->nav->max = $this->db->count_all('comments');
	if ($page * $limit <= $answer->nav->max){
		$answer->comments = $this->main_model->get_comments_limit($page, $limit);
	}
		
	$answer->is_ok = !count($err);
	$answer->err = $err;
		
	echo json_encode($answer);
}

// МОДЕЛЬ
function get_comments_limit($page=0, $limit=3){
	$this->db->order_by("id", "desc");
	$query = $this->db->get('comments', $limit, $page * $limit);
	return $query->result_array();
}


Я прошу прощения за столь большое количество кода в вопросе, но я не имел представление как по другому раскрыть свой вопрос.

Все что я выше написал, работает как часики, но из таблицы выводятся все подряд записи. Прошу помочь, разобраться как вывести только те которые содержат нужный параметр "key_c". Потому как я в растерянности, даже не понимаю что гуглить.

Заранее благодарен за любую помощь.
Ответить с цитированием
  #2 (permalink)  
Старый 29.12.2016, 17:17
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Сообщение от smart-create
большое количество кода в вопросе
Действительно все лишнее, ибо вывести только те которые содержат нужный параметр "key_c" будет определятся запросом к базе, которого в коде нет. Если только те что "key_c", значит запрос должен содержать условие WHERE ....
Ответить с цитированием
  #3 (permalink)  
Старый 29.12.2016, 20:10
Профессор
Отправить личное сообщение для smart-create Посмотреть профиль Найти все сообщения от smart-create
 
Регистрация: 25.10.2016
Сообщений: 157

laimas, я даже не знаю как Вас благодарить, Вы вот практически одно слово сказали про WHERE, и сразу все стало на свои места. Вы не первый раз уже мне помогаете, а раз 10-й, и всегда четко, спасибо))

Я кое что добавил:

1) скрипт который определяет параметр из ссылки, разместил в глобальной зоне видимости, и добавил одну переменную:
var key_c = $('[name=comments_key]'),
	url = document.location.pathname,
	page_url = url.split('/')[2];
key_c.val(page_url);


2) Эту переменную передал на сервер, через аякс который загружает записи:
function load_comments(page){
	$.ajax({
		url: '/main_c/loadComments',
		type: 'POST',
		data: {
			page: page || 0,
			limit: comment_limit,
			key_c: page_url,
		},
		dataType: 'json',
	})
	.done(function(result){
		if (result.is_ok){
			create_nav(result.nav);
			create_comments(result.comments, true);
		}
	});
}


3) Принял эту переменную и использовал её в качестве параметра для условия WHERE:
// КОНТРОЛЛЕР
function loadComments() {
		
	$page = isset($_POST['page']) ? (int)$_POST['page'] : 0;
	$limit = isset($_POST['limit']) ? (int)$_POST['limit'] : 3;
	$key_c = $_POST['key_c'];
		
	$answer = new stdClass();
	$err = array();
		
	$answer->nav = new stdClass();
	$answer->nav->page = $page;
	$answer->nav->max = $this->db->count_all('comments');
	if ($page * $limit <= $answer->nav->max){
		$answer->comments = $this->main_model->get_comments_limit($page, $limit, $key_c);
	}
		
	$answer->is_ok = !count($err);
	$answer->err = $err;
		
	echo json_encode($answer);
}

// МОДЕЛЬ
function get_comments_limit($page=0, $limit=3, $key_c){
	$this->db->order_by("id", "desc");
	$query = $this->db->get_where('comments', array('key_c' => $key_c), $limit, $page * $limit);
	return $query->result_array();
}


И все заработало, НО как обычно не обошлось без НО (((
Выборка данных происходит так как мне и нужно, НО "сломалась" пагинация. Она не учитывает то, что теперь у меня выводятся только определенные строки, и показывает количество страниц, ка будто выводятся все записи. То есть - если бы выводились все строки то количество страниц было бы (например) 4, в каждой страничке по 3 записи, а по факту, с учетом того что выводятся только определенные строки, выводить всего (например) 3 записи, этого хватает на одну страничку, а внизу все равно отображается 4 страницы, когда начинаешь их переключать, то они просто пустые.
В целом ситуация понятна, мой алгоритм просто считает количество всех строк в таблице, делит их на 3 (число записей которое выводиться на одну страницу) и создает соответствующее количество страниц. Теперь мне нужно доработать алгоритм таким образом что бы он учитывал что из таблицы выводятся не все записи.

Вот только я пока не имею не малейшего понятия как это сделать.

Я понимаю что это нагло с моей стороны, и Вы конечно же нечего мне не должны)) Но я очень Вас прошу, посмотреть весь мой алгоритм и подсказать как его доработать. Буду невероятно благодарен и обещаю в новогоднюю ночь выпить за Ваше здоровье бутылку шампанского
Ответить с цитированием
  #4 (permalink)  
Старый 29.12.2016, 20:19
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Сообщение от smart-create
Она не учитывает то, что теперь у меня выводятся только определенные строки, и показывает количество страниц, ка будто выводятся все записи.
Чтобы разбить вывод на страницы определенными порциями сначала нужно получить количество всех записей, что и делает этот запрос:

$answer->nav->max = $this->db->count_all('comments');

А если хотим вывести записи не все, а только удовлетворяющие условию, то и для навигатора получать нужно общее количество не всех записей, а удовлетворяющих условию, то есть в этом запросе также должно быть условие WHERE ...
Ответить с цитированием
  #5 (permalink)  
Старый 29.12.2016, 20:44
Профессор
Отправить личное сообщение для smart-create Посмотреть профиль Найти все сообщения от smart-create
 
Регистрация: 25.10.2016
Сообщений: 157

laimas, мне даже стыдно что я об этом не подумал, в любом случае теперь все работает как нужно. Спасибо Вам огромное и низкий поклон!
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вывод значения из JSON с помощью JS Win_D Общие вопросы Javascript 9 15.09.2016 10:15
JQuery вывод текста элементов таблицы javaphp Events/DOM/Window 3 04.03.2016 10:42
Книги по Ajax BaVa Учебные материалы 18 18.08.2013 14:05
Обработка ajax запроса c Content-Type:text/plain c помощью php stalker7 Серверные языки и технологии 0 29.06.2013 15:57
Вывод значения каждой 10 строки таблицы nik_neman jQuery 3 16.02.2012 18:50